package me.baicai.weixin.identity.service.impl;

import com.alibaba.fastjson.JSONObject;
import me.baicai.exception.domain.GcbException;
import me.baicai.exception.repository.GcbExceptionRepository;
import me.baicai.utils.StringUtils;
import me.baicai.weixin.conf.OrderKey;
import me.baicai.weixin.entity.gcb.Advertising;
import me.baicai.weixin.entity.gcb.Query;
import me.baicai.weixin.entity.order.Order;
import me.baicai.weixin.identity.repository.*;
import me.baicai.weixin.application.BasicService;
import me.baicai.weixin.application.Result;
import me.baicai.weixin.conf.IdentityKey;
import me.baicai.weixin.entity.gcb.PageEntity;
import me.baicai.weixin.entity.identity.AgentApply;
import me.baicai.weixin.entity.identity.Identity;
import me.baicai.weixin.entity.order.Account;
import me.baicai.weixin.identity.service.AgentService;
import me.baicai.weixin.identity.service.LoginService;
import me.baicai.weixin.identity.service.ManageService;
import me.baicai.weixin.utils.HttpClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.*;


/**
 * @description:
 * @author: [ 超级大白菜 ]
 * @date: 2019-11-09 16:20
 */

@Service
public class LoginServiceImpl extends BasicService implements LoginService
{

    @Autowired
    private LoginRepository loginRepository;

    @Autowired
    private AgentApplyRepository agentApplyRepository;

    @Autowired
    private HelpRepository helpRepository;

    @Autowired
    private AccountRepository accountRepository;

    @Autowired
    private OrderRepository orderRepository;

    @Autowired
    private MoneyLogRepository moneyLogRepository;

    @Autowired
    private DeviceRepository deviceRepository;

    @Autowired
    private ManageService manageService;

    @Autowired
    private AgentService agentService;

    @Autowired
    private GcbExceptionRepository gcbExceptionRepository;

    @Autowired
    private ShopRepository shopRepository;

    @Override
    public Result wxLogin(String code)
    {
        JSONObject json = HttpClient.getRequest(HttpClient.getUserUrl + code);
        if (null == json)
            return null;
        if (json.containsKey("openid"))
        {
            if (loginRepository.existsByOpenid(json.getString("openid")))
            {
                List<Order> order = orderRepository.findOrderByCustomeridAndOrderstatus(
                    json.get("openid").toString(), OrderKey.进行中);
                if (null != order && order.size() > 0)
                {
                    order.get(0).setShop(shopRepository.getById(order.get(0).getShopid()));
                    json.put("order", order);
                    json.put("device", deviceRepository.findBySn(order.get(0).getDevicesn()));
                }
                json.put("customer", loginRepository.findByOpenid(json.getString("openid")));
                return this.success(json);
            }
            else
            {
                return this.error(json, 401);
            }
        }

        return this.error(500, "参数有误,无法成功连接微信");
    }

    @Override
    public Result registered(String openid, String nickName, String avatarUrl, int gender,
                             String country, String province, String city, String language)
    {

        GcbException gcbException = new GcbException();
        gcbException.setCreated(new Date());
        gcbException.setText(openid);
        gcbException.setParameter(nickName);
        gcbException.setMethod("reg");
        gcbExceptionRepository.save(gcbException);

        if (openid.equalsIgnoreCase("[object Null]"))
        {
            return this.error("本次openid 获取异常");
        }

        if (loginRepository.existsByOpenid(openid))
        {
            return this.error("已经注册了的OpenID");
        }

        Account account = new Account(openid);
        account = accountRepository.save(account);
        Identity identity = new Identity(openid, "", "", nickName, avatarUrl, gender, country,
            province, city, language, new Date(),
            IdentityKey.customer, account.getId());
        return this.success(loginRepository.saveAndFlush(identity));
    }

    @Override
    public Result agentApply(String openid, String name, String tel, String weixin, String channel,
                             String province, String city, String area, String address,
                             String type, Integer size, String shop)
    {
        AgentApply agentApply = new AgentApply(openid, name, tel, weixin, channel, province, city,
            area, "", address, new Date(), type, size, shop);
        agentApplyRepository.save(agentApply);
        return this.success();
    }

    @Override
    public Result helpList()
    {
        return this.success(helpRepository.findAll());
    }

    @Override
    public Result index(String openid)
    {
        return this.success(loginRepository.findByOpenid(openid));
    }

    @Override
    public Result orders(String openid, Integer status, String beginDate, String endDate,
                         Integer page)
    {
        Pageable pageable = new PageEntity(page, 10, Sort.Direction.DESC, "created");
        return this.success(
            orderRepository.findAllByCustomeridAndOrderstatus(openid, status, beginDate, endDate,
                pageable));
    }

    @Override
    public Result nearbyShop(String latitude, String longitude)
    {
        return this.success(helpRepository.nearbyShop(latitude, longitude));
    }

    @Override
    public Result income(String openid, String type) {
        Map map = new HashMap();

        map.put("totalprofit", moneyLogRepository.leiji(openid, type));
        map.put("today", moneyLogRepository.jintian(openid, type));
        map.put("yesterday", moneyLogRepository.zuotian(openid, type));
        map.put("sevenProfit", moneyLogRepository.qitian(openid, type));
        map.put("thirtyProfit", moneyLogRepository.sanshitian(openid, type));
        map.put("chart", moneyLogRepository.tubiao(openid, type));

        if (type.equalsIgnoreCase("agent")) {
            map.put("mineShop", moneyLogRepository.mineShop(openid, type));
            map.put("ordernum", moneyLogRepository.jintianAgent(openid, type));
        } else {
            map.put("mineShop", moneyLogRepository.mineShopShop(openid, type));
            map.put("ordernum", moneyLogRepository.jintianOrder(openid, type));
        }
        map.put("monthList", moneyLogRepository.month(openid, type));

        List<JSONObject> list = moneyLogRepository.yesTerDayList(openid, type);
        map.put("yesterdayList", null == list || list.size() == 0 ? this.yesterdayList() : list);
        return this.success(map);
    }

    private List<JSONObject> yesterdayList()
    {
        ArrayList<JSONObject> pastDaysList = new ArrayList<>();
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("amount", 0);
        jsonObject.put("hours", "01");
        pastDaysList.add(jsonObject);
        jsonObject = new JSONObject();
        jsonObject.put("amount", 0);
        jsonObject.put("hours", "06");
        pastDaysList.add(jsonObject);
        jsonObject = new JSONObject();
        jsonObject.put("amount", 0);
        jsonObject.put("hours", "12");
        pastDaysList.add(jsonObject);
        jsonObject = new JSONObject();
        jsonObject.put("amount", 0);
        jsonObject.put("hours", "18");
        pastDaysList.add(jsonObject);
        jsonObject = new JSONObject();
        jsonObject.put("amount", 0);
        jsonObject.put("hours", "22");
        pastDaysList.add(jsonObject);
        return pastDaysList;
    }

    /**
     * 获取过去第几天的日期
     *
     * @param past
     * @return
     */
    private String getPastDate(int past)
    {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DAY_OF_YEAR, calendar.get(Calendar.DAY_OF_YEAR) - past);
        Date today = calendar.getTime();
        SimpleDateFormat format = new SimpleDateFormat("MM-dd");
        String result = format.format(today);
        return result;
    }

    /**
     * 获取过去或者未来 任意天内的日期数组
     *
     * @param intervals intervals天内
     * @return 日期数组
     */
    private List<JSONObject> chart(int intervals)
    {
        ArrayList<JSONObject> pastDaysList = new ArrayList<>();
        for (int i = intervals; i > 0; i--)
        {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("click_date", getPastDate(i));
            jsonObject.put("amount", 0.00F);
            pastDaysList.add(jsonObject);
        }
        return pastDaysList;
    }

    @Override
    public Result identity(Query query)
    {
        Pageable pageable = new PageEntity(query.getPage(), query.getSize(), Sort.Direction.DESC,
            "id");
        Map map = new HashMap();

        if (StringUtils.isNotBlank(query.getType()) && StringUtils.isNotBlank(query.getValue()))
        {
            switch (query.getType())
            {
                case "id":
                    return this.success(
                        loginRepository.findAllById(Integer.valueOf(query.getValue()), pageable));
                case "name":
                    return this.success(
                        loginRepository.findAllByNameLike("%" + query.getValue() + "%", pageable));
                case "nickName":
                    return this.success(
                        loginRepository.findAllByNickNameLike("%" + query.getValue() + "%",
                            pageable));
                case "openid":
                    return this.success(
                        loginRepository.findAllByOpenid(query.getValue(), pageable));
            }
            return this.success(map);
        }
        return this.success(loginRepository.findAll(pageable));
    }

    @Override
    public Result identity(Integer id)
    {
        Identity identity = loginRepository.getById(id);
        if (null == identity)
            return this.error(404, "不存在的用户");
        if (!identity.getType().equalsIgnoreCase(IdentityKey.customer))
            return this.error(404, "只能删除普通用户");
        loginRepository.delete(identity);
        return this.success();
    }

    @Override
    public Result identity(Account account)
    {
        return this.success(accountRepository.saveAndFlush(account));
    }

    @Override
    public Result showApply(String openid, String type)
    {
        return this.success(agentApplyRepository.findAllByType(type));
    }

    @Override
    public Result processApply(String openid, Integer id, Integer commission, String name,
                               String type)
    {
        AgentApply agentApply = agentApplyRepository.findAgentApplyById(id);

        if (type.equalsIgnoreCase("refuse"))
        {
            agentApplyRepository.deleteById(id);
            return this.success();
        }

        if (null == agentApply)
            return this.error("不存在的数据");

        Identity identity = loginRepository.findByOpenid(agentApply.getOpenid());
        if (!identity.getType().equalsIgnoreCase(IdentityKey.customer))
            return this.error("只限普通用户申请, 该对象已经为 : " + identity.getType());

        agentApplyRepository.deleteById(id);
        if (agentApply.getType().equalsIgnoreCase(IdentityKey.shop))
        {
            manageService.submitShop(openid, agentApply.getName(),
                agentApply.getTel(), agentApply.getAddress(), commission, identity.getId(),
                agentApply.getName(), "", "");
        }
        else
        {
            agentService.submitAgent(openid, identity.getId(), agentApply.getName(),
                agentApply.getTel(), agentApply.getAddress(), commission);
        }

        return this.success();
    }

}
